/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 *
 */

import fse from 'fs-extra';

import { AppJson } from '../../../options/configure/app-json-options.js';
import { ConfigJson } from '../../../options/configure/config-json-options.js';
import { ModuleJson } from '../../../options/configure/module-json-options.js';
import { getJson5Obj } from '../../json-util.js';
import { OhosLogger } from '../../log/ohos-logger.js';
import { ValidateUtil } from '../../validate/validate-util.js';
import { ValidatorStore } from '../../validate/validator-store.js';
import { configFileLoader } from '../config-file-loader.js';

const log: OhosLogger = OhosLogger.getLogger('ResModelLoader');

class ResModelLoader {
  private appJsonSchemaPath: string | undefined = undefined;
  private moduleJsonSchemaPath: string | undefined = undefined;

  public getAppJson(appJsonPath: string): AppJson.AppOptObj {
    return this.getResModelJsonObj(appJsonPath, this.appJsonSchemaPath);
  }

  public getModuleJson(moduleJsonPath: string): ModuleJson.ModuleOptObj {
    return this.getResModelJsonObj(moduleJsonPath, this.moduleJsonSchemaPath);
  }

  public getConfigJson(configJsonPath: string): ConfigJson.ConfigOptObj {
    return this.getResModelJsonObj(configJsonPath, undefined);
  }

  public setAppJson(appJsonPath: string, appJsonObj: AppJson.AppOptObj) {
    if (this.appJsonSchemaPath === undefined) {
      log.printErrorExit('SCHEMA_PATH_NOT_INITIALIZED', [appJsonPath]);
    }
    this.setResModelJsonObj(appJsonPath, appJsonObj, this.appJsonSchemaPath);
  }

  public setModuleJson(moduleJsonPath: string, moduleJsonObj: ModuleJson.ModuleOptObj) {
    if (this.moduleJsonSchemaPath === undefined) {
      log.printErrorExit('SCHEMA_PATH_NOT_INITIALIZED', [moduleJsonPath]);
    }
    this.setResModelJsonObj(moduleJsonPath, moduleJsonObj, this.moduleJsonSchemaPath);
  }

  /**
   * 从configFileLoader中读取一个配置文件，如果不存在则会从文件中读取
   * @param jsonPath
   * @param schemaPath 校验的schema文件路径
   * @private
   */
  private getResModelJsonObj(jsonPath: string, schemaPath: string | undefined): any {
    const resModelJsonObj = configFileLoader.getConfigFileJson(jsonPath);
    if (resModelJsonObj) {
      return resModelJsonObj;
    }

    if (resModelJsonObj === null) {
      return undefined;
    }

    if (fse.existsSync(jsonPath)) {
      // 如果是第一次加载，读取文件并应用替换，将替换后的存入map
      const json5Obj = getJson5Obj(jsonPath);
      this.setResModelJsonObj(jsonPath, json5Obj, schemaPath);
      return json5Obj;
    } else {
      log.debug(`not found resModel json file in : ${jsonPath}`);
      this.setResModelJsonObj(jsonPath, null, undefined);
      return undefined;
    }
  }

  private setResModelJsonObj(jsonPath: string, jsonObj: any, schemaPath: string | undefined) {
    schemaPath && this.validateBuildProfile(jsonObj, schemaPath);
    configFileLoader.setConfigFileJson(jsonPath, jsonObj);
  }

  protected validateBuildProfile(obj: object, schemaPath: string) {
    const validator = ValidatorStore.addValidator(schemaPath);
    try {
      ValidateUtil.schemaCheckJSObject(obj, undefined, validator);
    } catch (e) {
      if (e instanceof Error) {
        log.errorMessageExit(e.name, e.message);
      }
    }
  }

  public initSchemaPath(appJsonSchemaPath: string, moduleJsonSchemaPath: string) {
    this.appJsonSchemaPath = appJsonSchemaPath;
    this.moduleJsonSchemaPath = moduleJsonSchemaPath;
  }

  public clean() {
    this.appJsonSchemaPath = undefined;
    this.moduleJsonSchemaPath = undefined;
  }
}

export const resModelLoader: ResModelLoader = new ResModelLoader();
